/**
 * 格式化日期
 * @param date 日期对象
 * @param fmt 格式化字符串，如 'yyyy-MM-dd hh:mm:ss'
 * @returns 格式化后的日期字符串
 */
export function formateDate(date: Date, fmt: string): string {
  if (!(date instanceof Date) || isNaN(date.getTime())) {
    return '';
  }

  if (/(y+)/.test(fmt)) {
    fmt = fmt.replace(
      RegExp.$1,
      (date.getFullYear() + '').substr(4 - RegExp.$1.length)
    );
  }

  const o: Record<string, number> = {
    'M+': date.getMonth() + 1,
    'd+': date.getDate(),
    'h+': date.getHours(),
    'm+': date.getMinutes(),
    's+': date.getSeconds(),
    'S+': date.getMilliseconds(),
  };

  for (const k in o) {
    if (new RegExp(`(${k})`).test(fmt)) {
      const str = o[k] + '';
      fmt = fmt.replace(
        RegExp.$1,
        RegExp.$1.length === 1 ? str : padLeftZero(str)
      );
    }
  }
  return fmt;
}

/**
 * 左边补0函数
 * @param str 字符串
 * @returns 补0后的字符串
 */
function padLeftZero(str: string): string {
  return ('00' + str).substr(str.length);
}

/**
 * 格式化文件大小
 * @param bytes 字节数
 * @param decimals 小数位数，默认2位
 * @returns 格式化后的文件大小字符串
 */
export function formatFileSize(bytes: number, decimals: number = 2): string {
  if (bytes === 0) return '0 Bytes';

  const k = 1024;
  const dm = decimals < 0 ? 0 : decimals;
  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];

  const i = Math.floor(Math.log(bytes) / Math.log(k));

  return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}

/**
 * 格式化数字，添加千分位分隔符
 * @param num 数字
 * @param decimals 小数位数
 * @returns 格式化后的数字字符串
 */
export function formatNumber(num: number, decimals?: number): string {
  if (isNaN(num)) return '0';

  let result = num.toString();

  if (decimals !== undefined) {
    result = num.toFixed(decimals);
  }

  return result.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}

/**
 * 格式化百分比
 * @param value 数值
 * @param total 总数
 * @param decimals 小数位数，默认2位
 * @returns 百分比字符串
 */
export function formatPercentage(value: number, total: number, decimals: number = 2): string {
  if (total === 0) return '0%';
  const percentage = (value / total) * 100;
  return percentage.toFixed(decimals) + '%';
}

/**
 * 格式化时间戳为相对时间
 * @param timestamp 时间戳
 * @returns 相对时间字符串
 */
export function formatRelativeTime(timestamp: number | Date): string {
  const now = new Date().getTime();
  const time = timestamp instanceof Date ? timestamp.getTime() : timestamp;
  const diff = now - time;

  const minute = 60 * 1000;
  const hour = minute * 60;
  const day = hour * 24;
  const week = day * 7;
  const month = day * 30;
  const year = day * 365;

  if (diff < minute) {
    return '刚刚';
  } else if (diff < hour) {
    return Math.floor(diff / minute) + '分钟前';
  } else if (diff < day) {
    return Math.floor(diff / hour) + '小时前';
  } else if (diff < week) {
    return Math.floor(diff / day) + '天前';
  } else if (diff < month) {
    return Math.floor(diff / week) + '周前';
  } else if (diff < year) {
    return Math.floor(diff / month) + '个月前';
  } else {
    return Math.floor(diff / year) + '年前';
  }
}

/**
 * 格式化手机号码
 * @param phone 手机号码
 * @returns 格式化后的手机号码
 */
export function formatPhone(phone: string): string {
  if (!phone) return '';
  const cleaned = phone.replace(/\D/g, '');
  if (cleaned.length === 11) {
    return cleaned.replace(/(\d{3})(\d{4})(\d{4})/, '$1 $2 $3');
  }
  return phone;
}

/**
 * 格式化身份证号码（隐藏中间部分）
 * @param idCard 身份证号码
 * @returns 格式化后的身份证号码
 */
export function formatIdCard(idCard: string): string {
  if (!idCard) return '';
  if (idCard.length === 18) {
    return idCard.replace(/(\d{6})\d{8}(\d{4})/, '$1********$2');
  } else if (idCard.length === 15) {
    return idCard.replace(/(\d{6})\d{6}(\d{3})/, '$1******$2');
  }
  return idCard;
}

/**
 * 格式化银行卡号（隐藏中间部分）
 * @param bankCard 银行卡号
 * @returns 格式化后的银行卡号
 */
export function formatBankCard(bankCard: string): string {
  if (!bankCard) return '';
  const cleaned = bankCard.replace(/\s/g, '');
  if (cleaned.length >= 16) {
    return cleaned.replace(/(\d{4})\d+(\d{4})/, '$1 **** **** $2');
  }
  return bankCard;
}

/**
 * 格式化金额（添加货币符号和千分位）
 * @param amount 金额
 * @param currency 货币符号，默认￥
 * @param decimals 小数位数，默认2位
 * @returns 格式化后的金额字符串
 */
export function formatCurrency(amount: number, currency: string = '￥', decimals: number = 2): string {
  if (isNaN(amount)) return currency + '0.00';
  return currency + formatNumber(amount, decimals);
} 